﻿using DBLayer.Datacontext;
using ModelLayer;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace DBLayer
{
    public class DbUserAchievementOp
    {
        public DbUserAchievementOp()
        {
        }

        /// <summary>
        /// Insert UserAchievement in database
        /// </summary>
        /// <param name="user"></param>
        /// <param name="achievement"></param>
        /// <returns>return 1 for succes. -1 for failure.</returns>
        public int InsertUserAchievement(UserAchievement userAchievement)
        {
            RLADataContext db = new RLADataContext();
            int result = -1;
            try
            {
                db.DBUserAchievements.InsertOnSubmit(ConvUAchToDbUAch(userAchievement));
                db.SubmitChanges();
                result = 1;
            }
            catch (SqlException e)
            {
                Console.WriteLine("SQL error message");
                Console.WriteLine(e.Message);
                result = -2;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                result = -3;
            }
            return result;
        }

        public List<UserAchievement> GetUserAchievements(User myUser)
        {
            List<UserAchievement> retList = new List<UserAchievement>();
            RLADataContext db = new RLADataContext();

            foreach (var dbUserAchievement in db.DBUserAchievements.Where(uach => uach.DBUser.userId == myUser.UserId))
            {
                UserAchievement userAch = ConvDbUachToUAch(dbUserAchievement);
                retList.Add(userAch);
            }

            return retList;
        }

        /// <summary>
        /// Converts UserAchievement to DatacontextUserAchievement
        /// </summary>
        /// <param name="user"></param>
        /// <param name="achievement"></param>
        /// <returns></returns>
        public DBUserAchievement ConvUAchToDbUAch(UserAchievement userAchievement)
        {
            DBUserAchievement dbUAch = new DBUserAchievement();
            dbUAch.fk_AchievementId = userAchievement.Achievement.AchievementId;
            dbUAch.fk_UserId = userAchievement.User.UserId;
            dbUAch.status = (int)userAchievement.CurrentStatus;
            return dbUAch;
        }

        /// <summary>
        /// Converts DataContextUserAchievment to UserAvhievement
        /// </summary>
        /// <param name="dbUserAchievement"></param>
        /// <returns></returns>
        public UserAchievement ConvDbUachToUAch(DBUserAchievement dbUserAchievement)
        {
            DbUserOp dbUser = new DbUserOp();
            DbAchievementOp dbAchievement = new DbAchievementOp();

            UserAchievement uAch = new UserAchievement();
            uAch.Achievement = dbAchievement.ConvertDbAchievementToAchievement(dbUserAchievement.DBAchievement);

            uAch.Achievement.Participants = dbAchievement.GetAchievementUserList(uAch.Achievement);
            uAch.CurrentStatus = (UserAchievement.Status)dbUserAchievement.status;
            uAch.User = dbUser.ConvertDbUserToUser(dbUserAchievement.DBUser);

            return uAch;
        }

        /// <summary>
        /// <para>Updates an UserAchievement (with changed status) in DB.</para>
        /// <para>Returns:</para>
        /// <para> 1 if successfull</para>
        /// <para>-1: Default error code</para>
        /// <para>-2: SQL exception</para>
        /// <para>-3: General Exception</para>
        /// <para>-4: UserAchievement was not found in DB</para>
        /// </summary>
        /// <param name="userAchievement"></param>
        /// <returns></returns>
        public int SetUserAchievementStatus(UserAchievement userAchievement)
        {
            RLADataContext db = new RLADataContext();
            DBUserAchievement dbUserAchievement = ConvUAchToDbUAch(userAchievement);

            DBUserAchievement modifiedDbUserAchievement = db.DBUserAchievements.SingleOrDefault(ua =>
                (ua.DBAchievement.achievementId == dbUserAchievement.fk_AchievementId) &&
                (ua.DBUser.userId == dbUserAchievement.fk_UserId));

            int result = -1;

            try
            {
                modifiedDbUserAchievement.status = (int)userAchievement.CurrentStatus;

                db.SubmitChanges();
                result = 1;
            }
            catch (SqlException e)
            {
                result = -2;
            }
            catch (Exception e)
            {
                result = -3;

                if (modifiedDbUserAchievement == null)
                {
                    result = -4;
                }
            }

            return result;
        }
    }
}